package com.cryptape.cita_wallet.activity;

import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import com.blankj.utilcode.util.GsonUtils;
import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.MapUtils;
import com.blankj.utilcode.util.ToastUtils;
import com.cryptape.cita_wallet.CytonApplication;
import com.cryptape.cita_wallet.bean.CurrencyPrice;
import com.cryptape.cita_wallet.bean.MiningWithdrawDetailBean;
import com.cryptape.cita_wallet.bean.NetworkWideMortgageBean;
import com.cryptape.cita_wallet.bean.RealTimeData;
import com.cryptape.cita_wallet.constant.ConstantUtil;
import com.cryptape.cita_wallet.net.callback.CommonCallback;
import com.cryptape.cita_wallet.net.common.BaseUrlUtils;
import com.cryptape.cita_wallet.net.common.NetWorkManager;
import com.cryptape.cita_wallet.net.common.RxSubscriber2;
import com.cryptape.cita_wallet.net.request.HttpRequestMode;
import com.cryptape.cita_wallet.net.response.BaseResponse;
import com.cryptape.cita_wallet.service.http.EthRpcService;
import com.cryptape.cita_wallet.service.http.TokenService;
import com.cryptape.cita_wallet.util.RSAUtils;
import com.cryptape.cita_wallet.util.db.DBWalletUtil;
import com.cryptape.cita_wallet.util.ether.EtherUtil;
import com.mangoworld.android.R;

import org.web3j.abi.FunctionEncoder;
import org.web3j.abi.FunctionReturnDecoder;
import org.web3j.abi.TypeReference;
import org.web3j.abi.datatypes.Address;
import org.web3j.abi.datatypes.Function;
import org.web3j.abi.datatypes.Type;
import org.web3j.abi.datatypes.generated.Int256;
import org.web3j.protocol.core.DefaultBlockParameterName;
import org.web3j.protocol.core.methods.request.Transaction;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import rx.Observable;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.functions.Func1;
import rx.schedulers.Schedulers;

/**
 * Created by dengming on 10/3/20.
 */

public class RealTimeDataActivity extends NBaseActivity {

    private TextView tv_allTotal_coins;
    private TextView tv_allTotal_coins_usd;
    private TextView tv_real_time_price;
    private TextView tv_real_time_circulation;
    private TextView tv_market_value_of_circulation;
    private TextView tv_all_network_mortgage;
    private TextView tv_mortgage_value;
    private TextView tv_operation_and_construction;
    private TextView tv_ecological_fund;
    private TextView tv_team_motivation;
    private TextView tv_total_ore_pool;
    private TextView tv_cumulative_destruction;
    private TextView tv_detail;
    private TextView mappingIndexTv;

    @Override
    protected int getContentLayout() {
        return R.layout.activity_real_time_data;
    }

    @Override
    protected void initView() {
        tv_allTotal_coins = findViewById(R.id.tv_allTotal_coins);
        tv_allTotal_coins_usd = findViewById(R.id.tv_allTotal_coins_usd);
        tv_real_time_price = findViewById(R.id.tv_real_time_price);
        tv_real_time_circulation = findViewById(R.id.tv_real_time_circulation);
        tv_market_value_of_circulation = findViewById(R.id.tv_market_value_of_circulation);
        tv_all_network_mortgage = findViewById(R.id.tv_all_network_mortgage);
        tv_mortgage_value = findViewById(R.id.tv_mortgage_value);
        tv_operation_and_construction = findViewById(R.id.tv_operation_and_construction);
        tv_ecological_fund = findViewById(R.id.tv_ecological_fund);
        tv_team_motivation = findViewById(R.id.tv_team_motivation);
        tv_total_ore_pool = findViewById(R.id.tv_total_ore_pool);
        mappingIndexTv = findViewById(R.id.mappingIndexTv);
        tv_cumulative_destruction = findViewById(R.id.tv_cumulative_destruction);
        tv_detail = findViewById(R.id.tv_detail);

        findViewById(R.id.ll_cumulative_destruction).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String url = "https://cn.etherscan.com/token/0x8a845fc339ceb022a695281554890429a34df120?a=0x0000000000000000000000000000000000000000";
                SimpleWebActivity.gotoSimpleWeb(RealTimeDataActivity.this, url, getString(R.string.real_time_data));
            }
        });

        tv_detail.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SimpleWebActivity.gotoSimpleWeb(RealTimeDataActivity.this, "https://cn.etherscan.com/address/" + ConstantUtil.MToken, getString(R.string.real_time_data));
            }
        });

        findViewById(R.id.ll_kuangchi).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String url = "https://cn.etherscan.com/token/0x8a845fc339ceb022a695281554890429a34df120?a=0xcbef66932ad14ad571410257aaa5bd002dd4ee18";
                https:
//cn.etherscan.com/address/0xcbef66932ad14ad571410257aaa5bd002dd4ee18
                SimpleWebActivity.gotoSimpleWeb(RealTimeDataActivity.this, url, getString(R.string.real_time_data));

            }
        });

        findViewById(R.id.ll_yunying).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String url = "https://cn.etherscan.com/token/0x8a845fc339ceb022a695281554890429a34df120?a=0x60f1bea63494910360c43d3af0c57c693cc046b1";
                https:
//cn.etherscan.com/address/0xcbef66932ad14ad571410257aaa5bd002dd4ee18
                SimpleWebActivity.gotoSimpleWeb(RealTimeDataActivity.this, url, getString(R.string.real_time_data));

            }
        });
        findViewById(R.id.ll_shengtai).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String url = "https://cn.etherscan.com/token/0x8a845fc339ceb022a695281554890429a34df120?a=0x4cf1bb9733098b6e170c6b7e8cf77d3ec3e3c9ab";
                https:
//cn.etherscan.com/address/0xcbef66932ad14ad571410257aaa5bd002dd4ee18
                SimpleWebActivity.gotoSimpleWeb(RealTimeDataActivity.this, url, getString(R.string.real_time_data));

            }
        });
        findViewById(R.id.ll_tuandui).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String url = "https://cn.etherscan.com/token/0x8a845fc339ceb022a695281554890429a34df120?a=0xd10f1a6e04090e90801713ead1167b6e871c4d46";
//                https://cn.etherscan.com/address/0xcbef66932ad14ad571410257aaa5bd002dd4ee18
                SimpleWebActivity.gotoSimpleWeb(RealTimeDataActivity.this, url, getString(R.string.real_time_data));

            }
        });

    }

    private String MGPPrice;
    private BigDecimal totalValueAmountTest = new BigDecimal("5000000000");
    private BigDecimal totalValueAmount = new BigDecimal("500000000");

    private void refreshPrice() {
        tv_real_time_price.setText("$" + MGPPrice);
        BigDecimal allTotal = totalValueAmount;
        if (EtherUtil.getEthNodeName().equals(ConstantUtil.ETH_ROPSTEN_NAME)) {
            allTotal = totalValueAmountTest;
        }
        tv_allTotal_coins.setText(allTotal.toString());
        tv_allTotal_coins_usd.setText(allTotal.multiply(new BigDecimal(MGPPrice)).setScale(0) + "");
//        tv_market_value_of_circulation.setText();
    }

    @Override
    protected void initData() {
        NetWorkManager.getRequest().queryCurrency(BaseUrlUtils.PRICE_MGP)
                .observeOn(io.reactivex.android.schedulers.AndroidSchedulers.mainThread())
                .subscribe(new RxSubscriber2<BaseResponse<CurrencyPrice>>(this, false) {
                    @Override
                    public void onFail(String failMsg) {
                        LogUtils.dTag("queryCurrency==", "onFail failMsg = " + failMsg);
                    }

                    @Override
                    public void onSuccess(BaseResponse<CurrencyPrice> data) {
                        LogUtils.dTag("queryCurrency==", "onSuccess data = " + GsonUtils.toJson(data));
                        try {
                            if (data.isSuccess()) {
                                MGPPrice = ((CurrencyPrice) data.getData()).getPrice().toPlainString();
                                CytonApplication.getInstance().MGPPrice = MGPPrice;
                                refreshPrice();
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }

                    }
                });
        try {
            HttpRequestMode.getRealTimeIndex(RealTimeDataActivity.this, true, new CommonCallback() {
                @Override
                public void onSuccess(Object data, String successMsg, int responseSuccessCode) {
                    Observable.fromCallable(() -> {
                        RealTimeData realTimeData = new RealTimeData();
                        if (data != null) {
                            NetworkWideMortgageBean networkWideMortgageBean = (NetworkWideMortgageBean) data;
                            if (networkWideMortgageBean.getMgpNum() != null) {
                                realTimeData.setAllMortgage(new BigDecimal(networkWideMortgageBean.getMgpNum()));
                            }
                            realTimeData.setTransferSpeed(networkWideMortgageBean.getTransferSpeed());
                        }
                        realTimeData.setMGPPrice(new BigDecimal(CytonApplication.getInstance().MGPPrice == null ? "0" : CytonApplication.getInstance().MGPPrice));
                        try {
                            BigDecimal balance = queryBalance("0xcbef66932ad14ad571410257aaa5bd002dd4ee18");
                            if (balance != null) {
                                realTimeData.setKuangchizongliang(balance);
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        try {
                            BigDecimal balance = queryBalance("0x4cf1bb9733098b6e170c6b7e8cf77d3ec3e3c9ab");
                            if (balance != null) {
                                realTimeData.setShengTaiJijin(balance);
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        try {
                            BigDecimal balance = queryBalance("0xd10f1a6e04090e90801713ead1167b6e871c4d46");
                            if (balance != null) {
                                realTimeData.setTuanduiJili(balance);
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        try {
                            BigDecimal balance = queryBalance("0x60f1bea63494910360c43d3af0c57c693cc046b1");
                            if (balance != null) {
                                realTimeData.setYunYingJianshe(balance);
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        String supplyData = "0x18160ddd";//createTotalSupplyData();
                        String address = DBWalletUtil.getCurrentWallet(CytonApplication.getInstance()).address;
                        Transaction totalSupply = Transaction.createEthCallTransaction(ConstantUtil.getMGPToken(), ConstantUtil.getMGPToken(), supplyData);
                        try {
                            BigInteger result = null;
                            String supply = EthRpcService.service.ethCall(totalSupply, DefaultBlockParameterName.LATEST).send().getValue();
                            if (!TextUtils.isEmpty(supply) && !ConstantUtil.RPC_RESULT_ZERO.equals(supply)) {
                                List<TypeReference<Type>> intTypes = new ArrayList<>();
                                intTypes.clear();
                                intTypes.add(new TypeReference<Type>() {
                                    @Override
                                    public java.lang.reflect.Type getType() {
                                        return Int256.class;
                                    }
                                });
                                Int256 balance = (Int256) FunctionReturnDecoder.decode(supply, intTypes).get(0);
                                result = balance.getValue().divide(new BigInteger("10").pow(18));
                                realTimeData.setZongLiang(new BigDecimal(result));
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        return realTimeData;
                    })
                            .subscribeOn(Schedulers.newThread())
                            .observeOn(AndroidSchedulers.mainThread())
                            .subscribe(new Subscriber<RealTimeData>() {
                                @Override
                                public void onCompleted() {

                                }

                                @Override
                                public void onError(Throwable e) {

                                }

                                @Override
                                public void onNext(RealTimeData data) {
                                    if (data == null) {
                                        return;
                                    }
                                    tv_real_time_price.setText("$" + data.getMGPPrice());
                                    BigDecimal allTotal = totalValueAmount;
                                    if (EtherUtil.getEthNodeName().equals(ConstantUtil.ETH_ROPSTEN_NAME)) {
                                        allTotal = totalValueAmountTest;
                                    }
                                    tv_allTotal_coins.setText(data.getZongLiang().setScale(0, BigDecimal.ROUND_HALF_DOWN).toString());
                                    tv_all_network_mortgage.setText(data.getAllMortgage().setScale(0, BigDecimal.ROUND_HALF_DOWN).toString() + "");
                                    tv_mortgage_value.setText("$" + data.getMGPPrice().multiply(data.getAllMortgage()).setScale(0, BigDecimal.ROUND_HALF_DOWN).toString());
                                    tv_operation_and_construction.setText(data.getYunYingJianshe().setScale(0, BigDecimal.ROUND_HALF_DOWN).toString());
                                    tv_ecological_fund.setText(data.getShengTaiJijin().setScale(0, BigDecimal.ROUND_HALF_DOWN).toString());
                                    tv_team_motivation.setText(data.getTuanduiJili().setScale(0, BigDecimal.ROUND_HALF_DOWN).toString());
                                    tv_total_ore_pool.setText(data.getKuangchizongliang().setScale(0, BigDecimal.ROUND_HALF_DOWN).toString());

                                    BigDecimal realTimeCir = data.getZongLiang()
                                            .subtract(data.getKuangchizongliang())
                                            .subtract(data.getShengTaiJijin())
                                            .subtract(data.getTuanduiJili())
                                            .subtract(data.getYunYingJianshe())
                                            .subtract(data.getAllMortgage());
                                    tv_real_time_circulation.setText(realTimeCir.setScale(0, BigDecimal.ROUND_HALF_DOWN).toString());
                                    tv_market_value_of_circulation.setText("$" + realTimeCir.multiply(data.getMGPPrice()).setScale(0, BigDecimal.ROUND_HALF_DOWN).toString());
                                    tv_cumulative_destruction.setText(allTotal.subtract(data.getZongLiang()).setScale(0, BigDecimal.ROUND_HALF_DOWN).toString());
//                        tv_allTotal_coins_usd.setText("$" +data.getZongLiang().multiply(data.getMGPPrice()).setScale(0));
                                    tv_allTotal_coins_usd.setText("$" + data.getZongLiang().multiply(data.getMGPPrice()).setScale(0, BigDecimal.ROUND_HALF_DOWN).toString());
                                    mappingIndexTv.setText(data.getTransferSpeed());
                                }
                            });

                }

                @Override
                public void onFailure(String msg, int responseFailCode) {
                    ToastUtils.showLong(msg);
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private BigDecimal queryBalance(String address) {
        Function function = new Function(
                "balanceOf",
                Arrays.asList(new Address(address)),  // Solidity Types in smart contract functions
                Arrays.asList(new TypeReference<Type>() {
                }));

        String encodedFunction = FunctionEncoder.encode(function);
        org.web3j.protocol.core.methods.response.EthCall response = null;
        try {
            response = EthRpcService.service.ethCall(
                    Transaction.createEthCallTransaction(address, ConstantUtil.getMGPToken(), encodedFunction),
                    DefaultBlockParameterName.LATEST)
                    .send();
        } catch (Exception e) {
            e.printStackTrace();
            return BigDecimal.ZERO;
        }
        String returnValue = response.getValue(); //返回16进制余额
        returnValue = returnValue.substring(2);
        BigInteger balance = new BigInteger(returnValue, 16);
        return new BigDecimal(balance.divide(new BigInteger("10").pow(18)));
    }

    @Override
    protected void initAction() {

    }
}
